﻿/*************************************************************************************
 * 文 件 名:   HK_FreeCam
 * 
 * 描    述:   漫游摄像机控制脚本，运行时使用，主要用于场景编辑时测试使用。
 *            1.按住WASD键进行前后左右移动，QE键进行上下移动；
 *            2.按住鼠标右键进行视角旋转；
 *            3.按住Shift进行位移加速；
 *            4.滚动鼠标滚轮进行视野缩放；
 * 
 * 版    本：  V1.0
 * 创 建 者：  京产肠饭
 * 创建时间：  2021/8/25
 * 链   接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using UnityEngine;

/// <summary>
/// 自由摄像机脚本工具
/// </summary>
public class HK_FreeCam : MonoBehaviour
{
    [SerializeField, Header("摄像机移动速度：")]
    float initMoveSpeed = 10;
    float nowMoveSpeed;

    [SerializeField, Header("摄像机旋转速度")]
    float rotationSpeed = 300f;

    Transform mainCamera_TF;//获取摄像机

    [SerializeField, Header("X轴限制范围：")]
    Vector2 xRangeof3D = new Vector3(-45, 45);

    bool isQuicken;

    Vector3 camTargetPos;
    Vector3 camTargetEuler;
    float camFieldOfViewTarget;

    void Start()
    {
        mainCamera_TF = Camera.main.transform;
        camTargetPos = mainCamera_TF.position;
        camTargetEuler = mainCamera_TF.localEulerAngles;
        camFieldOfViewTarget = Camera.main.fieldOfView;
        isQuicken = false;
        nowMoveSpeed = initMoveSpeed;
    }

    void LateUpdate()
    {
        ControlCam();
        LimitCamXAxisRange(xRangeof3D);
        AddSpeed();
        ZoomCamera();
        LerpCameraPos();
        LerpCameraRot();
    }

    /// <summary>
    /// 3D视角的控制
    /// </summary>
    void ControlCam()
    {
        if (Input.GetKey(KeyCode.W))
            camTargetPos = camTargetPos + mainCamera_TF.forward * nowMoveSpeed * Time.deltaTime;

        if (Input.GetKey(KeyCode.S))
            camTargetPos = camTargetPos - mainCamera_TF.forward * nowMoveSpeed * Time.deltaTime;

        if (Input.GetKey(KeyCode.A))
            camTargetPos = camTargetPos - mainCamera_TF.right * nowMoveSpeed * Time.deltaTime;

        if (Input.GetKey(KeyCode.D))
            camTargetPos = camTargetPos + mainCamera_TF.right * nowMoveSpeed * Time.deltaTime;

        if (Input.GetKey(KeyCode.Q))
            camTargetPos = camTargetPos + Vector3.up * nowMoveSpeed * Time.deltaTime;

        if (Input.GetKey(KeyCode.E))
            camTargetPos = camTargetPos + Vector3.down * nowMoveSpeed * Time.deltaTime;

        if (Input.GetMouseButton(1))
        {
            camTargetEuler = camTargetEuler + Vector3.up * Input.GetAxisRaw("Mouse X") * rotationSpeed * Time.deltaTime;
            camTargetEuler = camTargetEuler + Vector3.left * Input.GetAxisRaw("Mouse Y") * rotationSpeed * Time.deltaTime;
            Cursor.visible = false;
        }

        if (Input.GetMouseButtonUp(1))
            Cursor.visible = true;
    }

    /// <summary>
    /// 限制摄像机俯仰角
    /// </summary>
    /// <param name="xAxis"></param>
    void LimitCamXAxisRange(Vector2 xAxis)
    {
        //当数据突然变到0左右时 会增加到360
        if (camTargetEuler.x > 340)
        {
            camTargetEuler.x = camTargetEuler.x - 360;
            mainCamera_TF.localEulerAngles = camTargetEuler;
        }

        if (camTargetEuler.x > xAxis.y)
            camTargetEuler.x = xAxis.y;

        if (camTargetEuler.x < xAxis.x)
            camTargetEuler.x = xAxis.x;
    }

    /// <summary>
    /// shift 加速
    /// </summary>
    void AddSpeed()
    {
        if (Input.GetKey(KeyCode.LeftShift))
        {
            nowMoveSpeed = initMoveSpeed * 3;
            isQuicken = true;
        }
        if (Input.GetKeyUp(KeyCode.LeftShift))
        {
            isQuicken = false;
        }

        if (!isQuicken)
        {
            if (nowMoveSpeed > initMoveSpeed)
            {
                nowMoveSpeed -= (100 * Time.deltaTime);
            }
            else
            {
                nowMoveSpeed = initMoveSpeed;
            }
        }
    }

    /// <summary>
    /// 滚动鼠标中键缩放摄像机
    /// </summary>
    void ZoomCamera()
    {
        //滚动鼠标滑轮缩放摄像机
        if (Input.GetAxis("Mouse ScrollWheel") > 0)
        {
            if (camFieldOfViewTarget >= 40)
                camFieldOfViewTarget -= 80 * Time.deltaTime;

        }
        if (Input.GetAxis("Mouse ScrollWheel") < 0)
        {
            if (camFieldOfViewTarget <= 80)
                camFieldOfViewTarget += 80 * Time.deltaTime;
        }

        Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, camFieldOfViewTarget, Time.deltaTime * 10);
    }

    /// <summary>
    /// 摄像机位置 平滑插值
    /// </summary>
    void LerpCameraPos()
    {
        if (Vector3.Distance(mainCamera_TF.position, camTargetPos) > 0.1f)
        {
            mainCamera_TF.position = Vector3.Lerp(mainCamera_TF.position, camTargetPos, Time.deltaTime * 10);
        }
    }

    /// <summary>
    /// 摄像机旋转 平滑插值
    /// </summary>
    void LerpCameraRot()
    {
        if (Quaternion.Dot(mainCamera_TF.rotation, Quaternion.Euler(camTargetEuler)) != 1)
        {
            mainCamera_TF.rotation = Quaternion.Lerp(mainCamera_TF.rotation, Quaternion.Euler(camTargetEuler), Time.deltaTime * 10);
        }
    }
}
